1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package sun.net.ftp.impl;
26
27 import java.net.*;
28 import java.io.*;
29 import java.security.AccessController;
30 import java.security.PrivilegedAction;
31 import java.text.DateFormat;
32 import java.text.ParseException;
33 import java.text.SimpleDateFormat;
34 import java.util.ArrayList;
35 import java.util.Calendar;
36 import java.util.Date;
37 import java.util.Iterator;
38 import java.util.List;
39 import java.util.TimeZone;
40 import java.util.Vector;
41 import java.util.regex.Matcher;
42 import java.util.regex.Pattern;
43 import javax.net.ssl.SSLSocket;
44 import javax.net.ssl.SSLSocketFactory;
45 import sun.misc.BASE64Decoder;
46 import sun.misc.BASE64Encoder;
47 import sun.net.ftp.*;
48 import sun.util.logging.PlatformLogger;
49
50
51 public class FtpClient extends sun.net.ftp.FtpClient {
52
53 private static int defaultSoTimeout;
54 private static int defaultConnectTimeout;
55 private static final PlatformLogger logger =
56 PlatformLogger.getLogger("sun.net.ftp.FtpClient");
57 private Proxy proxy;
58 private Socket server;
59 private PrintStream out;
60 private InputStream in;
61 private int readTimeout = -1;
62 private int connectTimeout = -1;
63
64
65 private static String encoding = "ISO8859_1";
66
67 private InetSocketAddress serverAddr;
68 private boolean replyPending = false;
69 private boolean loggedIn = false;
70 private boolean useCrypto = false;
71 private SSLSocketFactory sslFact;
72 private Socket oldSocket;
73
74 private Vector<String> serverResponse = new Vector<String>(1);
75
76 private FtpReplyCode lastReplyCode = null;
77
78 private String welcomeMsg;
79 private boolean passiveMode = true;
80 private TransferType type = TransferType.BINARY;
81 private long restartOffset = 0;
82 private long lastTransSize = -1;
83 private String lastFileName;
84
85
86
87 private static String[] patStrings = {
88
89 "([\\-ld](?:[r\\-][w\\-][x\\-]){3})\\s*\\d+ (\\w+)\\s*(\\w+)\\s*(\\d+)\\s*([A-Z][a-z][a-z]\\s*\\d+)\\s*(\\d\\d:\\d\\d)\\s*(\\p{Print}*)",
90
91 "([\\-ld](?:[r\\-][w\\-][x\\-]){3})\\s*\\d+ (\\w+)\\s*(\\w+)\\s*(\\d+)\\s*([A-Z][a-z][a-z]\\s*\\d+)\\s*(\\d{4})\\s*(\\p{Print}*)",
92
93 "(\\d{2}/\\d{2}/\\d{4})\\s*(\\d{2}:\\d{2}[ap])\\s*((?:[0-9,]+)|(?:<DIR>))\\s*(\\p{Graph}*)",
94
95 "(\\d{2}-\\d{2}-\\d{2})\\s*(\\d{2}:\\d{2}[AP]M)\\s*((?:[0-9,]+)|(?:<DIR>))\\s*(\\p{Graph}*)"
96 };
97 private static int[][] patternGroups = {
98
99
100 {7, 4, 5, 6, 0, 1, 2, 3},
101 {7, 4, 5, 0, 6, 1, 2, 3},
102 {4, 3, 1, 2, 0, 0, 0, 0},
103 {4, 3, 1, 2, 0, 0, 0, 0}};
104 private static Pattern[] patterns;
105 private static Pattern linkp = Pattern.compile("(\\p{Print}+) \\-\\> (\\p{Print}+)$");
106 private DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, java.util.Locale.US);
107
108 static {
109 final int vals[] = {0, 0};
110 final String encs[] = {null};
111
112 AccessController.doPrivileged(
113 new PrivilegedAction<Object>() {
114
115 public Object run() {
116 vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue();
117 vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue();
118 encs[0] = System.getProperty("file.encoding", "ISO8859_1");
119 return null;
120 }
121 });
122 if (vals[0] == 0) {
123 defaultSoTimeout = -1;
124 } else {
125 defaultSoTimeout = vals[0];
126 }
127
128 if (vals[1] == 0) {
129 defaultConnectTimeout = -1;
130 } else {
131 defaultConnectTimeout = vals[1];
132 }
133
134 encoding = encs[0];
135 try {
136 if (!isASCIISuperset(encoding)) {
137 encoding = "ISO8859_1";
138 }
139 } catch (Exception e) {
140 encoding = "ISO8859_1";
141 }
142
143 patterns = new Pattern[patStrings.length];
144 for (int i = 0; i < patStrings.length; i++) {
145 patterns[i] = Pattern.compile(patStrings[i]);
146 }
147 }
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 private static boolean isASCIISuperset(String encoding) throws Exception {
168 String chkS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
169 "abcdefghijklmnopqrstuvwxyz-_.!~*'();/?:@&=+$,";
170
171
172 byte[] chkB = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72,
173 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99,
174 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
175 115, 116, 117, 118, 119, 120, 121, 122, 45, 95, 46, 33, 126, 42, 39, 40, 41, 59,
176 47, 63, 58, 64, 38, 61, 43, 36, 44};
177
178 byte[] b = chkS.getBytes(encoding);
179 return java.util.Arrays.equals(b, chkB);
180 }
181
182 private class DefaultParser implements FtpDirParser {
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 private DefaultParser() {
202 }
203
204 public FtpDirEntry parseLine(String line) {
205 String fdate = null;
206 String fsize = null;
207 String time = null;
208 String filename = null;
209 String permstring = null;
210 String username = null;
211 String groupname = null;
212 boolean dir = false;
213 Calendar now = Calendar.getInstance();
214 int year = now.get(Calendar.YEAR);
215
216 Matcher m = null;
217 for (int j = 0; j < patterns.length; j++) {
218 m = patterns[j].matcher(line);
219 if (m.find()) {
220
221
222 filename = m.group(patternGroups[j][0]);
223 fsize = m.group(patternGroups[j][1]);
224 fdate = m.group(patternGroups[j][2]);
225 if (patternGroups[j][4] > 0) {
226 fdate += (", " + m.group(patternGroups[j][4]));
227 } else if (patternGroups[j][3] > 0) {
228 fdate += (", " + String.valueOf(year));
229 }
230 if (patternGroups[j][3] > 0) {
231 time = m.group(patternGroups[j][3]);
232 }
233 if (patternGroups[j][5] > 0) {
234 permstring = m.group(patternGroups[j][5]);
235 dir = permstring.startsWith("d");
236 }
237 if (patternGroups[j][6] > 0) {
238 username = m.group(patternGroups[j][6]);
239 }
240 if (patternGroups[j][7] > 0) {
241 groupname = m.group(patternGroups[j][7]);
242 }
243
244 if ("<DIR>".equals(fsize)) {
245 dir = true;
246 fsize = null;
247 }
248 }
249 }
250
251 if (filename != null) {
252 Date d;
253 try {
254 d = df.parse(fdate);
255 } catch (Exception e) {
256 d = null;
257 }
258 if (d != null && time != null) {
259 int c = time.indexOf(":");
260 now.setTime(d);
261 now.set(Calendar.HOUR, Integer.parseInt(time.substring(0, c)));
262 now.set(Calendar.MINUTE, Integer.parseInt(time.substring(c + 1)));
263 d = now.getTime();
264 }
265
266
267 Matcher m2 = linkp.matcher(filename);
268 if (m2.find()) {
269
270 filename = m2.group(1);
271 }
272 boolean[][] perms = new boolean[3][3];
273 for (int i = 0; i < 3; i++) {
274 for (int j = 0; j < 3; j++) {
275 perms[i][j] = (permstring.charAt((i * 3) + j) != '-');
276 }
277 }
278 FtpDirEntry file = new FtpDirEntry(filename);
279 file.setUser(username).setGroup(groupname);
280 file.setSize(Long.parseLong(fsize)).setLastModified(d);
281 file.setPermissions(perms);
282 file.setType(dir ? FtpDirEntry.Type.DIR : (line.charAt(0) == 'l' ? FtpDirEntry.Type.LINK : FtpDirEntry.Type.FILE));
283 return file;
284 }
285 return null;
286 }
287 }
288
289 private class MLSxParser implements FtpDirParser {
290
291 private SimpleDateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");
292
293 public FtpDirEntry parseLine(String line) {
294 String name = null;
295 int i = line.lastIndexOf(";");
296 if (i > 0) {
297 name = line.substring(i + 1).trim();
298 line = line.substring(0, i);
299 } else {
300 name = line.trim();
301 line = "";
302 }
303 FtpDirEntry file = new FtpDirEntry(name);
304 while (!line.isEmpty()) {
305 String s;
306 i = line.indexOf(";");
307 if (i > 0) {
308 s = line.substring(0, i);
309 line = line.substring(i + 1);
310 } else {
311 s = line;
312 line = "";
313 }
314 i = s.indexOf("=");
315 if (i > 0) {
316 String fact = s.substring(0, i);
317 String value = s.substring(i + 1);
318 file.addFact(fact, value);
319 }
320 }
321 String s = file.getFact("Size");
322 if (s != null) {
323 file.setSize(Long.parseLong(s));
324 }
325 s = file.getFact("Modify");
326 if (s != null) {
327 Date d = null;
328 try {
329 d = df.parse(s);
330 } catch (ParseException ex) {
331 }
332 if (d != null) {
333 file.setLastModified(d);
334 }
335 }
336 s = file.getFact("Create");
337 if (s != null) {
338 Date d = null;
339 try {
340 d = df.parse(s);
341 } catch (ParseException ex) {
342 }
343 if (d != null) {
344 file.setCreated(d);
345 }
346 }
347 s = file.getFact("Type");
348 if (s != null) {
349 if (s.equalsIgnoreCase("file")) {
350 file.setType(FtpDirEntry.Type.FILE);
351 }
352 if (s.equalsIgnoreCase("dir")) {
353 file.setType(FtpDirEntry.Type.DIR);
354 }
355 if (s.equalsIgnoreCase("cdir")) {
356 file.setType(FtpDirEntry.Type.CDIR);
357 }
358 if (s.equalsIgnoreCase("pdir")) {
359 file.setType(FtpDirEntry.Type.PDIR);
360 }
361 }
362 return file;
363 }
364 };
365 private FtpDirParser parser = new DefaultParser();
366 private FtpDirParser mlsxParser = new MLSxParser();
367 private static Pattern transPat = null;
368
369 private void getTransferSize() {
370 lastTransSize = -1;
371
372
373
374
375
376
377 String response = getLastResponseString();
378 if (transPat == null) {
379 transPat = Pattern.compile("150 Opening .*\\((\\d+) bytes\\).");
380 }
381 Matcher m = transPat.matcher(response);
382 if (m.find()) {
383 String s = m.group(1);
384 lastTransSize = Long.parseLong(s);
385 }
386 }
387
388
389
390
391
392
393 private void getTransferName() {
394 lastFileName = null;
395 String response = getLastResponseString();
396 int i = response.indexOf("unique file name:");
397 int e = response.lastIndexOf(')');
398 if (i >= 0) {
399 i += 17;
400 lastFileName = response.substring(i, e);
401 }
402 }
403
404
405
406
407
408 private int readServerResponse() throws IOException {
409 StringBuffer replyBuf = new StringBuffer(32);
410 int c;
411 int continuingCode = -1;
412 int code;
413 String response;
414
415 serverResponse.setSize(0);
416 while (true) {
417 while ((c = in.read()) != -1) {
418 if (c == '\r') {
419 if ((c = in.read()) != '\n') {
420 replyBuf.append('\r');
421 }
422 }
423 replyBuf.append((char) c);
424 if (c == '\n') {
425 break;
426 }
427 }
428 response = replyBuf.toString();
429 replyBuf.setLength(0);
430 if (logger.isLoggable(PlatformLogger.FINEST)) {
431 logger.finest("Server [" + serverAddr + "] --> " + response);
432 }
433
434 if (response.length() == 0) {
435 code = -1;
436 } else {
437 try {
438 code = Integer.parseInt(response.substring(0, 3));
439 } catch (NumberFormatException e) {
440 code = -1;
441 } catch (StringIndexOutOfBoundsException e) {
442
443
444 continue;
445 }
446 }
447 serverResponse.addElement(response);
448 if (continuingCode != -1) {
449
450 if (code != continuingCode ||
451 (response.length() >= 4 && response.charAt(3) == '-')) {
452 continue;
453 } else {
454
455 continuingCode = -1;
456 break;
457 }
458 } else if (response.length() >= 4 && response.charAt(3) == '-') {
459 continuingCode = code;
460 continue;
461 } else {
462 break;
463 }
464 }
465
466 return code;
467 }
468
469
470 private void sendServer(String cmd) {
471 out.print(cmd);
472 if (logger.isLoggable(PlatformLogger.FINEST)) {
473 logger.finest("Server [" + serverAddr + "] <-- " + cmd);
474 }
475 }
476
477
478 private String getResponseString() {
479 return serverResponse.elementAt(0);
480 }
481
482
483 private Vector<String> getResponseStrings() {
484 return serverResponse;
485 }
486
487
488
489
490
491
492
493 private boolean readReply() throws IOException {
494 lastReplyCode = FtpReplyCode.find(readServerResponse());
495
496 if (lastReplyCode.isPositivePreliminary()) {
497 replyPending = true;
498 return true;
499 }
500 if (lastReplyCode.isPositiveCompletion() || lastReplyCode.isPositiveIntermediate()) {
501 if (lastReplyCode == FtpReplyCode.CLOSING_DATA_CONNECTION) {
502 getTransferName();
503 }
504 return true;
505 }
506 return false;
507 }
508
509
510
511
512
513
514
515
516
517 private boolean issueCommand(String cmd) throws IOException {
518 if (!isConnected()) {
519 throw new IllegalStateException("Not connected");
520 }
521 if (replyPending) {
522 try {
523 completePending();
524 } catch (sun.net.ftp.FtpProtocolException e) {
525
526 }
527 }
528 sendServer(cmd + "\r\n");
529 return readReply();
530 }
531
532
533
534
535
536
537
538
539 private void issueCommandCheck(String cmd) throws sun.net.ftp.FtpProtocolException, IOException {
540 if (!issueCommand(cmd)) {
541 throw new sun.net.ftp.FtpProtocolException(cmd + ":" + getResponseString(), getLastReplyCode());
542 }
543 }
544 private static Pattern epsvPat = null;
545 private static Pattern pasvPat = null;
546
547
548
549
550
551
552
553
554 private Socket openPassiveDataConnection(String cmd) throws sun.net.ftp.FtpProtocolException, IOException {
555 String serverAnswer;
556 int port;
557 InetSocketAddress dest = null;
558
559
560
561
562
563
564
565
566
567
568
569
570 if (issueCommand("EPSV ALL")) {
571
572 issueCommandCheck("EPSV");
573 serverAnswer = getResponseString();
574
575
576
577
578
579
580
581 if (epsvPat == null) {
582 epsvPat = Pattern.compile("^229 .* \\(\\|\\|\\|(\\d+)\\|\\)");
583 }
584 Matcher m = epsvPat.matcher(serverAnswer);
585 if (!m.find()) {
586 throw new sun.net.ftp.FtpProtocolException("EPSV failed : " + serverAnswer);
587 }
588
589 String s = m.group(1);
590 port = Integer.parseInt(s);
591 InetAddress add = server.getInetAddress();
592 if (add != null) {
593 dest = new InetSocketAddress(add, port);
594 } else {
595
596
597
598
599 dest = InetSocketAddress.createUnresolved(serverAddr.getHostName(), port);
600 }
601 } else {
602
603 issueCommandCheck("PASV");
604 serverAnswer = getResponseString();
605
606
607
608
609
610
611
612
613
614
615
616
617
618 if (pasvPat == null) {
619 pasvPat = Pattern.compile("227 .* \\(?(\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}),(\\d{1,3}),(\\d{1,3})\\)?");
620 }
621 Matcher m = pasvPat.matcher(serverAnswer);
622 if (!m.find()) {
623 throw new sun.net.ftp.FtpProtocolException("PASV failed : " + serverAnswer);
624 }
625
626 port = Integer.parseInt(m.group(3)) + (Integer.parseInt(m.group(2)) << 8);
627
628 String s = m.group(1).replace(',', '.');
629 dest = new InetSocketAddress(s, port);
630 }
631
632 Socket s;
633 if (proxy != null) {
634 if (proxy.type() == Proxy.Type.SOCKS) {
635 s = AccessController.doPrivileged(
636 new PrivilegedAction<Socket>() {
637
638 public Socket run() {
639 return new Socket(proxy);
640 }
641 });
642 } else {
643 s = new Socket(Proxy.NO_PROXY);
644 }
645 } else {
646 s = new Socket();
647 }
648
649
650 s.bind(new InetSocketAddress(server.getLocalAddress(), 0));
651 if (connectTimeout >= 0) {
652 s.connect(dest, connectTimeout);
653 } else {
654 if (defaultConnectTimeout > 0) {
655 s.connect(dest, defaultConnectTimeout);
656 } else {
657 s.connect(dest);
658 }
659 }
660 if (readTimeout >= 0) {
661 s.setSoTimeout(readTimeout);
662 } else if (defaultSoTimeout > 0) {
663 s.setSoTimeout(defaultSoTimeout);
664 }
665 if (useCrypto) {
666 try {
667 s = sslFact.createSocket(s, dest.getHostName(), dest.getPort(), true);
668 } catch (Exception e) {
669 throw new sun.net.ftp.FtpProtocolException("Can't open secure data channel: " + e);
670 }
671 }
672 if (!issueCommand(cmd)) {
673 s.close();
674 if (getLastReplyCode() == FtpReplyCode.FILE_UNAVAILABLE) {
675
676 throw new FileNotFoundException(cmd);
677 }
678 throw new sun.net.ftp.FtpProtocolException(cmd + ":" + getResponseString(), getLastReplyCode());
679 }
680 return s;
681 }
682
683
684
685
686
687
688
689
690
691 private Socket openDataConnection(String cmd) throws sun.net.ftp.FtpProtocolException, IOException {
692 Socket clientSocket;
693
694 if (passiveMode) {
695 try {
696 return openPassiveDataConnection(cmd);
697 } catch (sun.net.ftp.FtpProtocolException e) {
698
699
700 String errmsg = e.getMessage();
701 if (!errmsg.startsWith("PASV") && !errmsg.startsWith("EPSV")) {
702 throw e;
703 }
704 }
705 }
706 ServerSocket portSocket;
707 InetAddress myAddress;
708 String portCmd;
709
710 if (proxy != null && proxy.type() == Proxy.Type.SOCKS) {
711
712
713
714 throw new sun.net.ftp.FtpProtocolException("Passive mode failed");
715 }
716
717
718 portSocket = new ServerSocket(0, 1, server.getLocalAddress());
719 try {
720 myAddress = portSocket.getInetAddress();
721 if (myAddress.isAnyLocalAddress()) {
722 myAddress = server.getLocalAddress();
723 }
724
725
726
727
728
729
730
731 portCmd = "EPRT |" + ((myAddress instanceof Inet6Address) ? "2" : "1") + "|" +
732 myAddress.getHostAddress() + "|" + portSocket.getLocalPort() + "|";
733 if (!issueCommand(portCmd) || !issueCommand(cmd)) {
734
735 portCmd = "PORT ";
736 byte[] addr = myAddress.getAddress();
737
738
739 for (int i = 0; i < addr.length; i++) {
740 portCmd = portCmd + (addr[i] & 0xFF) + ",";
741 }
742
743
744 portCmd = portCmd + ((portSocket.getLocalPort() >>> 8) & 0xff) + "," + (portSocket.getLocalPort() & 0xff);
745 issueCommandCheck(portCmd);
746 issueCommandCheck(cmd);
747 }
748
749
750 if (connectTimeout >= 0) {
751 portSocket.setSoTimeout(connectTimeout);
752 } else {
753 if (defaultConnectTimeout > 0) {
754 portSocket.setSoTimeout(defaultConnectTimeout);
755 }
756 }
757 clientSocket = portSocket.accept();
758 if (readTimeout >= 0) {
759 clientSocket.setSoTimeout(readTimeout);
760 } else {
761 if (defaultSoTimeout > 0) {
762 clientSocket.setSoTimeout(defaultSoTimeout);
763 }
764 }
765 } finally {
766 portSocket.close();
767 }
768 if (useCrypto) {
769 try {
770 clientSocket = sslFact.createSocket(clientSocket, serverAddr.getHostName(), serverAddr.getPort(), true);
771 } catch (Exception ex) {
772 throw new IOException(ex.getLocalizedMessage());
773 }
774 }
775 return clientSocket;
776 }
777
778 private InputStream createInputStream(InputStream in) {
779 if (type == TransferType.ASCII) {
780 return new sun.net.TelnetInputStream(in, false);
781 }
782 return in;
783 }
784
785 private OutputStream createOutputStream(OutputStream out) {
786 if (type == TransferType.ASCII) {
787 return new sun.net.TelnetOutputStream(out, false);
788 }
789 return out;
790 }
791
792
793
794
795
796
797 protected FtpClient() {
798 }
799
800
801
802
803
804
805 public static sun.net.ftp.FtpClient create() {
806 return new FtpClient();
807 }
808
809
810
811
812
813
814
815
816
817
818 public sun.net.ftp.FtpClient enablePassiveMode(boolean passive) {
819 passiveMode = passive;
820 return this;
821 }
822
823
824
825
826
827
828 public boolean isPassiveModeEnabled() {
829 return passiveMode;
830 }
831
832
833
834
835
836
837
838
839
840 public sun.net.ftp.FtpClient setConnectTimeout(int timeout) {
841 connectTimeout = timeout;
842 return this;
843 }
844
845
846
847
848
849
850
851 public int getConnectTimeout() {
852 return connectTimeout;
853 }
854
855
856
857
858
859
860
861
862 public sun.net.ftp.FtpClient setReadTimeout(int timeout) {
863 readTimeout = timeout;
864 return this;
865 }
866
867
868
869
870
871
872
873 public int getReadTimeout() {
874 return readTimeout;
875 }
876
877 public sun.net.ftp.FtpClient setProxy(Proxy p) {
878 proxy = p;
879 return this;
880 }
881
882
883
884
885
886
887
888
889 public Proxy getProxy() {
890 return proxy;
891 }
892
893
894
895
896
897
898
899 private void tryConnect(InetSocketAddress dest, int timeout) throws IOException {
900 if (isConnected()) {
901 disconnect();
902 }
903 server = doConnect(dest, timeout);
904 try {
905 out = new PrintStream(new BufferedOutputStream(server.getOutputStream()),
906 true, encoding);
907 } catch (UnsupportedEncodingException e) {
908 throw new InternalError(encoding + "encoding not found");
909 }
910 in = new BufferedInputStream(server.getInputStream());
911 }
912
913 private Socket doConnect(InetSocketAddress dest, int timeout) throws IOException {
914 Socket s;
915 if (proxy != null) {
916 if (proxy.type() == Proxy.Type.SOCKS) {
917 s = AccessController.doPrivileged(
918 new PrivilegedAction<Socket>() {
919
920 public Socket run() {
921 return new Socket(proxy);
922 }
923 });
924 } else {
925 s = new Socket(Proxy.NO_PROXY);
926 }
927 } else {
928 s = new Socket();
929 }
930
931
932
933
934 if (timeout >= 0) {
935 s.connect(dest, timeout);
936 } else {
937 if (connectTimeout >= 0) {
938 s.connect(dest, connectTimeout);
939 } else {
940 if (defaultConnectTimeout > 0) {
941 s.connect(dest, defaultConnectTimeout);
942 } else {
943 s.connect(dest);
944 }
945 }
946 }
947 if (readTimeout >= 0) {
948 s.setSoTimeout(readTimeout);
949 } else if (defaultSoTimeout > 0) {
950 s.setSoTimeout(defaultSoTimeout);
951 }
952 return s;
953 }
954
955 private void disconnect() throws IOException {
956 if (isConnected()) {
957 server.close();
958 }
959 server = null;
960 in = null;
961 out = null;
962 lastTransSize = -1;
963 lastFileName = null;
964 restartOffset = 0;
965 welcomeMsg = null;
966 lastReplyCode = null;
967 serverResponse.setSize(0);
968 }
969
970
971
972
973
974
975 public boolean isConnected() {
976 return server != null;
977 }
978
979 public SocketAddress getServerAddress() {
980 return server == null ? null : server.getRemoteSocketAddress();
981 }
982
983 public sun.net.ftp.FtpClient connect(SocketAddress dest) throws sun.net.ftp.FtpProtocolException, IOException {
984 return connect(dest, -1);
985 }
986
987
988
989
990
991
992
993 public sun.net.ftp.FtpClient connect(SocketAddress dest, int timeout) throws sun.net.ftp.FtpProtocolException, IOException {
994 if (!(dest instanceof InetSocketAddress)) {
995 throw new IllegalArgumentException("Wrong address type");
996 }
997 serverAddr = (InetSocketAddress) dest;
998 tryConnect(serverAddr, timeout);
999 if (!readReply()) {
1000 throw new sun.net.ftp.FtpProtocolException("Welcome message: " +
1001 getResponseString(), lastReplyCode);
1002 }
1003 welcomeMsg = getResponseString().substring(4);
1004 return this;
1005 }
1006
1007 private void tryLogin(String user, char[] password) throws sun.net.ftp.FtpProtocolException, IOException {
1008 issueCommandCheck("USER " + user);
1009
1010
1011
1012
1013 if (lastReplyCode == FtpReplyCode.NEED_PASSWORD) {
1014 if ((password != null) && (password.length > 0)) {
1015 issueCommandCheck("PASS " + String.valueOf(password));
1016 }
1017 }
1018 }
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 public sun.net.ftp.FtpClient login(String user, char[] password) throws sun.net.ftp.FtpProtocolException, IOException {
1029 if (!isConnected()) {
1030 throw new sun.net.ftp.FtpProtocolException("Not connected yet", FtpReplyCode.BAD_SEQUENCE);
1031 }
1032 if (user == null || user.length() == 0) {
1033 throw new IllegalArgumentException("User name can't be null or empty");
1034 }
1035 tryLogin(user, password);
1036
1037
1038
1039 String l;
1040 StringBuffer sb = new StringBuffer();
1041 for (int i = 0; i < serverResponse.size(); i++) {
1042 l = serverResponse.elementAt(i);
1043 if (l != null) {
1044 if (l.length() >= 4 && l.startsWith("230")) {
1045
1046 l = l.substring(4);
1047 }
1048 sb.append(l);
1049 }
1050 }
1051 welcomeMsg = sb.toString();
1052 loggedIn = true;
1053 return this;
1054 }
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066 public sun.net.ftp.FtpClient login(String user, char[] password, String account) throws sun.net.ftp.FtpProtocolException, IOException {
1067
1068 if (!isConnected()) {
1069 throw new sun.net.ftp.FtpProtocolException("Not connected yet", FtpReplyCode.BAD_SEQUENCE);
1070 }
1071 if (user == null || user.length() == 0) {
1072 throw new IllegalArgumentException("User name can't be null or empty");
1073 }
1074 tryLogin(user, password);
1075
1076
1077
1078
1079 if (lastReplyCode == FtpReplyCode.NEED_ACCOUNT) {
1080 issueCommandCheck("ACCT " + account);
1081 }
1082
1083
1084
1085 StringBuffer sb = new StringBuffer();
1086 if (serverResponse != null) {
1087 for (String l : serverResponse) {
1088 if (l != null) {
1089 if (l.length() >= 4 && l.startsWith("230")) {
1090
1091 l = l.substring(4);
1092 }
1093 sb.append(l);
1094 }
1095 }
1096 }
1097 welcomeMsg = sb.toString();
1098 loggedIn = true;
1099 return this;
1100 }
1101
1102
1103
1104
1105
1106
1107 public void close() throws IOException {
1108 if (isConnected()) {
1109 issueCommand("QUIT");
1110 loggedIn = false;
1111 }
1112 disconnect();
1113 }
1114
1115
1116
1117
1118
1119
1120 public boolean isLoggedIn() {
1121 return loggedIn;
1122 }
1123
1124
1125
1126
1127
1128
1129
1130
1131 public sun.net.ftp.FtpClient changeDirectory(String remoteDirectory) throws sun.net.ftp.FtpProtocolException, IOException {
1132 if (remoteDirectory == null || "".equals(remoteDirectory)) {
1133 throw new IllegalArgumentException("directory can't be null or empty");
1134 }
1135
1136 issueCommandCheck("CWD " + remoteDirectory);
1137 return this;
1138 }
1139
1140
1141
1142
1143
1144
1145
1146 public sun.net.ftp.FtpClient changeToParentDirectory() throws sun.net.ftp.FtpProtocolException, IOException {
1147 issueCommandCheck("CDUP");
1148 return this;
1149 }
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159 public String getWorkingDirectory() throws sun.net.ftp.FtpProtocolException, IOException {
1160 issueCommandCheck("PWD");
1161
1162
1163
1164
1165
1166 String answ = getResponseString();
1167 if (!answ.startsWith("257")) {
1168 return null;
1169 }
1170 return answ.substring(5, answ.lastIndexOf('"'));
1171 }
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184 public sun.net.ftp.FtpClient setRestartOffset(long offset) {
1185 if (offset < 0) {
1186 throw new IllegalArgumentException("offset can't be negative");
1187 }
1188 restartOffset = offset;
1189 return this;
1190 }
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206 public sun.net.ftp.FtpClient getFile(String name, OutputStream local) throws sun.net.ftp.FtpProtocolException, IOException {
1207 int mtu = 1500;
1208 if (restartOffset > 0) {
1209 Socket s;
1210 try {
1211 s = openDataConnection("REST " + restartOffset);
1212 } finally {
1213 restartOffset = 0;
1214 }
1215 issueCommandCheck("RETR " + name);
1216 getTransferSize();
1217 InputStream remote = createInputStream(s.getInputStream());
1218 byte[] buf = new byte[mtu * 10];
1219 int l;
1220 while ((l = remote.read(buf)) >= 0) {
1221 if (l > 0) {
1222 local.write(buf, 0, l);
1223 }
1224 }
1225 remote.close();
1226 } else {
1227 Socket s = openDataConnection("RETR " + name);
1228 getTransferSize();
1229 InputStream remote = createInputStream(s.getInputStream());
1230 byte[] buf = new byte[mtu * 10];
1231 int l;
1232 while ((l = remote.read(buf)) >= 0) {
1233 if (l > 0) {
1234 local.write(buf, 0, l);
1235 }
1236 }
1237 remote.close();
1238 }
1239 return completePending();
1240 }
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253 public InputStream getFileStream(String name) throws sun.net.ftp.FtpProtocolException, IOException {
1254 Socket s;
1255 if (restartOffset > 0) {
1256 try {
1257 s = openDataConnection("REST " + restartOffset);
1258 } finally {
1259 restartOffset = 0;
1260 }
1261 if (s == null) {
1262 return null;
1263 }
1264 issueCommandCheck("RETR " + name);
1265 getTransferSize();
1266 return createInputStream(s.getInputStream());
1267 }
1268
1269 s = openDataConnection("RETR " + name);
1270 if (s == null) {
1271 return null;
1272 }
1273 getTransferSize();
1274 return createInputStream(s.getInputStream());
1275 }
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302 public OutputStream putFileStream(String name, boolean unique) throws sun.net.ftp.FtpProtocolException, IOException {
1303 String cmd = unique ? "STOU " : "STOR ";
1304 Socket s = openDataConnection(cmd + name);
1305 if (s == null) {
1306 return null;
1307 }
1308 if (type == TransferType.BINARY) {
1309 return s.getOutputStream();
1310 }
1311 return new sun.net.TelnetOutputStream(s.getOutputStream(), false);
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332 public sun.net.ftp.FtpClient putFile(String name, InputStream local, boolean unique) throws sun.net.ftp.FtpProtocolException, IOException {
1333 String cmd = unique ? "STOU " : "STOR ";
1334 int mtu = 1500;
1335 if (type == TransferType.BINARY) {
1336 Socket s = openDataConnection(cmd + name);
1337 OutputStream remote = createOutputStream(s.getOutputStream());
1338 byte[] buf = new byte[mtu * 10];
1339 int l;
1340 while ((l = local.read(buf)) >= 0) {
1341 if (l > 0) {
1342 remote.write(buf, 0, l);
1343 }
1344 }
1345 remote.close();
1346 }
1347 return completePending();
1348 }
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362 public sun.net.ftp.FtpClient appendFile(String name, InputStream local) throws sun.net.ftp.FtpProtocolException, IOException {
1363 int mtu = 1500;
1364 Socket s = openDataConnection("APPE " + name);
1365 OutputStream remote = createOutputStream(s.getOutputStream());
1366 byte[] buf = new byte[mtu * 10];
1367 int l;
1368 while ((l = local.read(buf)) >= 0) {
1369 if (l > 0) {
1370 remote.write(buf, 0, l);
1371 }
1372 }
1373 remote.close();
1374 return completePending();
1375 }
1376
1377
1378
1379
1380
1381
1382
1383
1384 public sun.net.ftp.FtpClient rename(String from, String to) throws sun.net.ftp.FtpProtocolException, IOException {
1385 issueCommandCheck("RNFR " + from);
1386 issueCommandCheck("RNTO " + to);
1387 return this;
1388 }
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398 public sun.net.ftp.FtpClient deleteFile(String name) throws sun.net.ftp.FtpProtocolException, IOException {
1399 issueCommandCheck("DELE " + name);
1400 return this;
1401 }
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411 public sun.net.ftp.FtpClient makeDirectory(String name) throws sun.net.ftp.FtpProtocolException, IOException {
1412 issueCommandCheck("MKD " + name);
1413 return this;
1414 }
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425 public sun.net.ftp.FtpClient removeDirectory(String name) throws sun.net.ftp.FtpProtocolException, IOException {
1426 issueCommandCheck("RMD " + name);
1427 return this;
1428 }
1429
1430
1431
1432
1433
1434
1435
1436 public sun.net.ftp.FtpClient noop() throws sun.net.ftp.FtpProtocolException, IOException {
1437 issueCommandCheck("NOOP");
1438 return this;
1439 }
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456 public String getStatus(String name) throws sun.net.ftp.FtpProtocolException, IOException {
1457 issueCommandCheck((name == null ? "STAT" : "STAT " + name));
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482 Vector<String> resp = getResponseStrings();
1483 StringBuffer sb = new StringBuffer();
1484 for (int i = 1; i < resp.size() - 1; i++) {
1485 sb.append(resp.get(i));
1486 }
1487 return sb.toString();
1488 }
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505 public List<String> getFeatures() throws sun.net.ftp.FtpProtocolException, IOException {
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519 ArrayList<String> features = new ArrayList<String>();
1520 issueCommandCheck("FEAT");
1521 Vector<String> resp = getResponseStrings();
1522
1523
1524 for (int i = 1; i < resp.size() - 1; i++) {
1525 String s = resp.get(i);
1526
1527 features.add(s.substring(1, s.length() - 1));
1528 }
1529 return features;
1530 }
1531
1532
1533
1534
1535
1536
1537
1538
1539 public sun.net.ftp.FtpClient abort() throws sun.net.ftp.FtpProtocolException, IOException {
1540 issueCommandCheck("ABOR");
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559 return this;
1560 }
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595 public sun.net.ftp.FtpClient completePending() throws sun.net.ftp.FtpProtocolException, IOException {
1596 while (replyPending) {
1597 replyPending = false;
1598 if (!readReply()) {
1599 throw new sun.net.ftp.FtpProtocolException(getLastResponseString(), lastReplyCode);
1600 }
1601 }
1602 return this;
1603 }
1604
1605
1606
1607
1608
1609
1610 public sun.net.ftp.FtpClient reInit() throws sun.net.ftp.FtpProtocolException, IOException {
1611 issueCommandCheck("REIN");
1612 loggedIn = false;
1613 if (useCrypto) {
1614 if (server instanceof SSLSocket) {
1615 javax.net.ssl.SSLSession session = ((SSLSocket) server).getSession();
1616 session.invalidate();
1617
1618 server = oldSocket;
1619 oldSocket = null;
1620 try {
1621 out = new PrintStream(new BufferedOutputStream(server.getOutputStream()),
1622 true, encoding);
1623 } catch (UnsupportedEncodingException e) {
1624 throw new InternalError(encoding + "encoding not found");
1625 }
1626 in = new BufferedInputStream(server.getInputStream());
1627 }
1628 }
1629 useCrypto = false;
1630 return this;
1631 }
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641 public sun.net.ftp.FtpClient setType(TransferType type) throws sun.net.ftp.FtpProtocolException, IOException {
1642 String cmd = "NOOP";
1643
1644 this.type = type;
1645 if (type == TransferType.ASCII) {
1646 cmd = "TYPE A";
1647 }
1648 if (type == TransferType.BINARY) {
1649 cmd = "TYPE I";
1650 }
1651 if (type == TransferType.EBCDIC) {
1652 cmd = "TYPE E";
1653 }
1654 issueCommandCheck(cmd);
1655 return this;
1656 }
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671 public InputStream list(String path) throws sun.net.ftp.FtpProtocolException, IOException {
1672 Socket s;
1673 s = openDataConnection(path == null ? "LIST" : "LIST " + path);
1674 if (s != null) {
1675 return createInputStream(s.getInputStream());
1676 }
1677 return null;
1678 }
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695 public InputStream nameList(String path) throws sun.net.ftp.FtpProtocolException, IOException {
1696 Socket s;
1697 s = openDataConnection("NLST " + path);
1698 if (s != null) {
1699 return createInputStream(s.getInputStream());
1700 }
1701 return null;
1702 }
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717 public long getSize(String path) throws sun.net.ftp.FtpProtocolException, IOException {
1718 if (path == null || path.length() == 0) {
1719 throw new IllegalArgumentException("path can't be null or empty");
1720 }
1721 issueCommandCheck("SIZE " + path);
1722 if (lastReplyCode == FtpReplyCode.FILE_STATUS) {
1723 String s = getResponseString();
1724 s = s.substring(4, s.length() - 1);
1725 return Long.parseLong(s);
1726 }
1727 return -1;
1728 }
1729 private static String[] MDTMformats = {
1730 "yyyyMMddHHmmss.SSS",
1731 "yyyyMMddHHmmss"
1732 };
1733 private static SimpleDateFormat[] dateFormats = new SimpleDateFormat[MDTMformats.length];
1734
1735 static {
1736 for (int i = 0; i < MDTMformats.length; i++) {
1737 dateFormats[i] = new SimpleDateFormat(MDTMformats[i]);
1738 dateFormats[i].setTimeZone(TimeZone.getTimeZone("GMT"));
1739 }
1740 }
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754 public Date getLastModified(String path) throws sun.net.ftp.FtpProtocolException, IOException {
1755 issueCommandCheck("MDTM " + path);
1756 if (lastReplyCode == FtpReplyCode.FILE_STATUS) {
1757 String s = getResponseString().substring(4);
1758 Date d = null;
1759 for (SimpleDateFormat dateFormat : dateFormats) {
1760 try {
1761 d = dateFormat.parse(s);
1762 } catch (ParseException ex) {
1763 }
1764 if (d != null) {
1765 return d;
1766 }
1767 }
1768 }
1769 return null;
1770 }
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782 public sun.net.ftp.FtpClient setDirParser(FtpDirParser p) {
1783 parser = p;
1784 return this;
1785 }
1786
1787 private class FtpFileIterator implements Iterator<FtpDirEntry>, Closeable {
1788
1789 private BufferedReader in = null;
1790 private FtpDirEntry nextFile = null;
1791 private FtpDirParser fparser = null;
1792 private boolean eof = false;
1793
1794 public FtpFileIterator(FtpDirParser p, BufferedReader in) {
1795 this.in = in;
1796 this.fparser = p;
1797 readNext();
1798 }
1799
1800 private void readNext() {
1801 nextFile = null;
1802 if (eof) {
1803 return;
1804 }
1805 String line = null;
1806 try {
1807 do {
1808 line = in.readLine();
1809 if (line != null) {
1810 nextFile = fparser.parseLine(line);
1811 if (nextFile != null) {
1812 return;
1813 }
1814 }
1815 } while (line != null);
1816 in.close();
1817 } catch (IOException iOException) {
1818 }
1819 eof = true;
1820 }
1821
1822 public boolean hasNext() {
1823 return nextFile != null;
1824 }
1825
1826 public FtpDirEntry next() {
1827 FtpDirEntry ret = nextFile;
1828 readNext();
1829 return ret;
1830 }
1831
1832 public void remove() {
1833 throw new UnsupportedOperationException("Not supported yet.");
1834 }
1835
1836 public void close() throws IOException {
1837 if (in != null && !eof) {
1838 in.close();
1839 }
1840 eof = true;
1841 nextFile = null;
1842 }
1843 }
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864 public Iterator<FtpDirEntry> listFiles(String path) throws sun.net.ftp.FtpProtocolException, IOException {
1865 Socket s = null;
1866 BufferedReader sin = null;
1867 try {
1868 s = openDataConnection(path == null ? "MLSD" : "MLSD " + path);
1869 } catch (sun.net.ftp.FtpProtocolException FtpException) {
1870
1871
1872 }
1873
1874 if (s != null) {
1875 sin = new BufferedReader(new InputStreamReader(s.getInputStream()));
1876 return new FtpFileIterator(mlsxParser, sin);
1877 } else {
1878 s = openDataConnection(path == null ? "LIST" : "LIST " + path);
1879 if (s != null) {
1880 sin = new BufferedReader(new InputStreamReader(s.getInputStream()));
1881 return new FtpFileIterator(parser, sin);
1882 }
1883 }
1884 return null;
1885 }
1886
1887 private boolean sendSecurityData(byte[] buf) throws IOException {
1888 BASE64Encoder encoder = new BASE64Encoder();
1889 String s = encoder.encode(buf);
1890 return issueCommand("ADAT " + s);
1891 }
1892
1893 private byte[] getSecurityData() {
1894 String s = getLastResponseString();
1895 if (s.substring(4, 9).equalsIgnoreCase("ADAT=")) {
1896 BASE64Decoder decoder = new BASE64Decoder();
1897 try {
1898
1899
1900 return decoder.decodeBuffer(s.substring(9, s.length() - 1));
1901 } catch (IOException e) {
1902
1903 }
1904 }
1905 return null;
1906 }
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918 public sun.net.ftp.FtpClient useKerberos() throws sun.net.ftp.FtpProtocolException, IOException {
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952 return this;
1953 }
1954
1955
1956
1957
1958
1959
1960
1961 public String getWelcomeMsg() {
1962 return welcomeMsg;
1963 }
1964
1965
1966
1967
1968
1969
1970 public FtpReplyCode getLastReplyCode() {
1971 return lastReplyCode;
1972 }
1973
1974
1975
1976
1977
1978
1979
1980 public String getLastResponseString() {
1981 StringBuffer sb = new StringBuffer();
1982 if (serverResponse != null) {
1983 for (String l : serverResponse) {
1984 if (l != null) {
1985 sb.append(l);
1986 }
1987 }
1988 }
1989 return sb.toString();
1990 }
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000 public long getLastTransferSize() {
2001 return lastTransSize;
2002 }
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013 public String getLastFileName() {
2014 return lastFileName;
2015 }
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030 public sun.net.ftp.FtpClient startSecureSession() throws sun.net.ftp.FtpProtocolException, IOException {
2031 if (!isConnected()) {
2032 throw new sun.net.ftp.FtpProtocolException("Not connected yet", FtpReplyCode.BAD_SEQUENCE);
2033 }
2034 if (sslFact == null) {
2035 try {
2036 sslFact = (SSLSocketFactory) SSLSocketFactory.getDefault();
2037 } catch (Exception e) {
2038 throw new IOException(e.getLocalizedMessage());
2039 }
2040 }
2041 issueCommandCheck("AUTH TLS");
2042 Socket s = null;
2043 try {
2044 s = sslFact.createSocket(server, serverAddr.getHostName(), serverAddr.getPort(), true);
2045 } catch (javax.net.ssl.SSLException ssle) {
2046 try {
2047 disconnect();
2048 } catch (Exception e) {
2049 }
2050 throw ssle;
2051 }
2052
2053 oldSocket = server;
2054 server = s;
2055 try {
2056 out = new PrintStream(new BufferedOutputStream(server.getOutputStream()),
2057 true, encoding);
2058 } catch (UnsupportedEncodingException e) {
2059 throw new InternalError(encoding + "encoding not found");
2060 }
2061 in = new BufferedInputStream(server.getInputStream());
2062
2063 issueCommandCheck("PBSZ 0");
2064 issueCommandCheck("PROT P");
2065 useCrypto = true;
2066 return this;
2067 }
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078 public sun.net.ftp.FtpClient endSecureSession() throws sun.net.ftp.FtpProtocolException, IOException {
2079 if (!useCrypto) {
2080 return this;
2081 }
2082
2083 issueCommandCheck("CCC");
2084 issueCommandCheck("PROT C");
2085 useCrypto = false;
2086
2087 server = oldSocket;
2088 oldSocket = null;
2089 try {
2090 out = new PrintStream(new BufferedOutputStream(server.getOutputStream()),
2091 true, encoding);
2092 } catch (UnsupportedEncodingException e) {
2093 throw new InternalError(encoding + "encoding not found");
2094 }
2095 in = new BufferedInputStream(server.getInputStream());
2096
2097 return this;
2098 }
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108 public sun.net.ftp.FtpClient allocate(long size) throws sun.net.ftp.FtpProtocolException, IOException {
2109 issueCommandCheck("ALLO " + size);
2110 return this;
2111 }
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123 public sun.net.ftp.FtpClient structureMount(String struct) throws sun.net.ftp.FtpProtocolException, IOException {
2124 issueCommandCheck("SMNT " + struct);
2125 return this;
2126 }
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137 public String getSystem() throws sun.net.ftp.FtpProtocolException, IOException {
2138 issueCommandCheck("SYST");
2139
2140
2141
2142 String resp = getResponseString();
2143
2144 return resp.substring(4);
2145 }
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157 public String getHelp(String cmd) throws sun.net.ftp.FtpProtocolException, IOException {
2158 issueCommandCheck("HELP " + cmd);
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177 Vector<String> resp = getResponseStrings();
2178 if (resp.size() == 1) {
2179
2180 return resp.get(0).substring(4);
2181 }
2182
2183
2184 StringBuffer sb = new StringBuffer();
2185 for (int i = 1; i < resp.size() - 1; i++) {
2186 sb.append(resp.get(i).substring(3));
2187 }
2188 return sb.toString();
2189 }
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200 public sun.net.ftp.FtpClient siteCmd(String cmd) throws sun.net.ftp.FtpProtocolException, IOException {
2201 issueCommandCheck("SITE " + cmd);
2202 return this;
2203 }
2204 }